package com.mbc.common.manager;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRResultSetDataSource;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;

import com.mbc.common.CommonSingleton;
import com.mbc.common.dao.BranchDAO;
import com.mbc.common.dao.CommonDAOFactory;
import com.mbc.common.dao.DBManager;
import com.mbc.common.dao.DBManagerFactory;
import com.mbc.common.dao.IAIMSBranchDAO;
import com.mbc.common.dao.LogDAO;
import com.mbc.common.data.BranchDataList;
import com.mbc.common.data.ReferenceData;
import com.mbc.common.entities.Branch;
import com.mbc.common.entities.BranchRpt;
import com.mbc.common.entities.Log;
import com.mbc.common.exception.DataDuplicationException;
import com.mbc.common.exception.ForeignConflictException;
import com.mbc.common.utils.KeyGenerator;


public class BranchMgr extends AbstractMgr {
	
	private BranchDAO branchDAO;
	private IAIMSBranchDAO iaimsbranchDAO;
	private LogDAO logDAO;
	
	public BranchMgr(){}
	
	public BranchMgr(String sessionId){
		this.sessionId = sessionId;
	}
	
	public void createBranch(Branch branch)throws Exception{
		DBManager l_DBManager = DBManagerFactory.getDBManager(sessionId, DBManager.LINKED_IAIMS);
		openConnection();
		try {
			l_DBManager.beginTransaction();
			beginTransaction();
			
			branchDAO = CommonDAOFactory.getBranchDAO(dbManager.getConnection());
			iaimsbranchDAO = CommonDAOFactory.getIAIMSBranchDAO(l_DBManager.getConnection());
			logDAO = CommonDAOFactory.getLogDAO(getConnection());
			
			branch.setBranchId(KeyGenerator.generateKey(dbManager.getConnection()));
			
			branchDAO.create(branch);
			iaimsbranchDAO.create(branch);
			
			Log l_logentity = new Log();
			l_logentity.setTablename("Branch");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(branch.getBranchId());
			l_logentity.setUserid(branch.getUserid());
			l_logentity.setLogstatus(Log.__SAVE_DATA);
			logDAO.getData(l_logentity);
			
			l_DBManager.commitTransaction();
			commintTransaction();
		} catch (SQLException e) {
			l_DBManager.rollBackTransaction();
			rollbackTransaction();
			
			if(DataDuplicationException.UNIQUE_KEY_ERROR_CODE == e.getErrorCode())
				throw new DataDuplicationException(e.getMessage());
			else
				throw e;
		} finally {
			dbManager.closeConnection();
			l_DBManager.closeConnection();
		}
	}
	
	public void updateBranch(Branch branch)throws Exception{
		DBManager l_DBManager = DBManagerFactory.getDBManager(sessionId, DBManager.LINKED_IAIMS);
		openConnection();
		try {
			l_DBManager.beginTransaction();
			beginTransaction();
			
			branchDAO = CommonDAOFactory.getBranchDAO(dbManager.getConnection());
			iaimsbranchDAO = CommonDAOFactory.getIAIMSBranchDAO(l_DBManager.getConnection());
			
			branchDAO.update(branch);
			iaimsbranchDAO.update(branch);
			
			logDAO = CommonDAOFactory.getLogDAO(getConnection());
			Log l_logentity = new Log();
			l_logentity.setTablename("Branch");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(branch.getBranchId());
			l_logentity.setUserid(branch.getUserid());
			l_logentity.setLogstatus(Log.__UPDATE_DATA);
			logDAO.getData(l_logentity);
			
			commintTransaction();
			l_DBManager.commitTransaction();
		} catch (Exception e) {
			rollbackTransaction();
			l_DBManager.rollBackTransaction();
			throw e;
		} finally {
			dbManager.closeConnection();
			l_DBManager.closeConnection();
		}
	}
	
	public void deleteBranch(long key,long userid) throws Exception{
		DBManager l_DBManager = DBManagerFactory.getDBManager(sessionId, DBManager.LINKED_IAIMS);
		openConnection();
		try {
			l_DBManager.beginTransaction();
			beginTransaction();
			
			branchDAO = CommonDAOFactory.getBranchDAO(dbManager.getConnection());
			iaimsbranchDAO = CommonDAOFactory.getIAIMSBranchDAO(l_DBManager.getConnection());
			
			logDAO = CommonDAOFactory.getLogDAO(getConnection());
			Log l_logentity = new Log();
			l_logentity.setTablename("Branch");
			l_logentity.setLogkey(KeyGenerator.generateKey(getConnection()));
			l_logentity.setKey(key);
			l_logentity.setUserid(userid);
			l_logentity.setLogstatus(Log.__DELETE_DATA);
			logDAO.getData(l_logentity);
			
			branchDAO.delete(key);
			iaimsbranchDAO.delete(key);
			
			commintTransaction();
			l_DBManager.commitTransaction();
		} catch (SQLException e) {
			rollbackTransaction();
			l_DBManager.rollBackTransaction();
			if(e.getErrorCode() == ForeignConflictException.FOREIGN_CONFLICT_ERROR_CODE)
				throw new ForeignConflictException(e);
			else
				throw e;
		} finally {
			dbManager.closeConnection();
			l_DBManager.closeConnection();
		}
	}
	
	public Branch findBranch(long key) throws Exception{
		openConnection();
		try {
			branchDAO = CommonDAOFactory.getBranchDAO(dbManager.getConnection());
			return branchDAO.find(key);
		} catch (Exception e) {
			throw e;
		} finally {
			dbManager.closeConnection();
		}
	}
	
	public BranchDataList findBranch(Branch cri)throws Exception{
		openConnection();
		try {
			branchDAO = CommonDAOFactory.getBranchDAO(dbManager.getConnection());
			return branchDAO.getList(cri);
		} catch (Exception e) {
			throw e;
		} finally{
			dbManager.closeConnection();
		}
	}
	
	public ArrayList<Branch> getAllBranch()throws Exception{
		openConnection();
		try {
			branchDAO = CommonDAOFactory.getBranchDAO(dbManager.getConnection());
			return branchDAO.findAll();
		} catch (Exception e) {
			throw e;
		} finally{
			dbManager.closeConnection();
		}
	}
	
	public ArrayList<ReferenceData<Long>> getBranchRefList()throws Exception{
		openConnection();
		try {
			branchDAO = CommonDAOFactory.getBranchDAO(getConnection());
			return branchDAO.getBranchRefList();
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	/** MBC **/
	public Branch findBranchByCode(String code) throws Exception {
		openConnection();
		try {
			branchDAO = CommonDAOFactory.getBranchDAO(dbManager.getConnection());
			return branchDAO.findBranchByCode(code);
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}
	}
	
	//Report
	public JasperPrint prepareBranchReport(BranchRpt info) throws Exception {
		openConnection();
		JasperPrint l_jsPrint = null;
		try {
			branchDAO = CommonDAOFactory.getBranchDAO(getConnection());

			JRResultSetDataSource l_jrRS = new JRResultSetDataSource(branchDAO.prepareBranchReport(info));

			JasperReport l_jsRpt = (JasperReport) JRLoader
					.loadObjectFromFile(CommonSingleton.ABSOLUTE_PATH
							+ "reports/BranchRpt.jasper");
			HashMap<String, Object> l_params = new HashMap<String, Object>();
			l_params.put("company", "MBC");
			l_jsPrint = JasperFillManager.fillReport(l_jsRpt, l_params, l_jrRS);

		} catch (JRException je) {
			throw je;
		} catch (Exception e) {
			throw e;
		} finally {
			closeConnection();
		}

		return l_jsPrint;

	}
	
	public static long getIAIMSBranchCode(String branchCode, Connection localConnection, Connection linkedConnection)throws Exception{
		long l_key = 0;
		try {
			IAIMSBranchDAO l_iaimsBranchDAO = CommonDAOFactory.getIAIMSBranchDAO(linkedConnection);
			l_key = l_iaimsBranchDAO.getKeyByCode(branchCode);
			if(l_key == 0){
				Branch l_branch = CommonDAOFactory.getBranchDAO(localConnection).findBranchByCode(branchCode);
				l_branch.setBranchId(KeyGenerator.generateKey(linkedConnection));
				l_iaimsBranchDAO.create(l_branch);
				return l_branch.getBranchId();
			}
		} catch (Exception e) {
			throw e;
		}
		return l_key;
	}
}
